/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 shroud_transition_map.h

	$Header: /resource_editor/shroud_transition_map.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( SHROUD_TRANSITION_MAP_H_INCLUDED )
#define SHROUD_TRANSITION_MAP_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <cassert>
#include <vector>

#include "abstract_tile.h"
#include "adventure_tile_size.h"
#include "copy_on_write_ptr.h"
#include "isometric_map.h"
#include "map_point.h"
#include "uncopyable.h"

// --------------------------------------------------------------------------
// t_shroud_transition class
// --------------------------------------------------------------------------

class t_shroud_transition
{
public:
	// Member functions
	unsigned			get_id() const;
	unsigned			get_mask_set() const;
	t_tile_visibility	get_visibility() const;
	void				set_id( unsigned new_id );
	void				set_mask_set( unsigned new_mask_set );
	void				set_visibility( t_tile_visibility new_visibility );

private:
	// Data members
	unsigned short	m_visibility : 2;
	unsigned short	m_id : 9;         // 0-255 normal transition, 256-259 special corner transition
	unsigned short	m_mask_set : 5;   // Actual transition set used, 0-19.
};

// --------------------------------------------------------------------------
// t_shroud_transition members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline unsigned t_shroud_transition::get_id() const
{
	return m_id;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline unsigned t_shroud_transition::get_mask_set() const
{
	return m_mask_set;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_tile_visibility t_shroud_transition::get_visibility() const
{
	return t_tile_visibility( m_visibility );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline void t_shroud_transition::set_id( unsigned new_id )
{
	m_id = new_id;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline void t_shroud_transition::set_mask_set( unsigned new_mask_set )
{
	m_mask_set = new_mask_set;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline void t_shroud_transition::set_visibility( t_tile_visibility new_visibility )
{
	assert( new_visibility >= 0 && new_visibility < k_tile_visibility_count );
	m_visibility = new_visibility;
}

// --------------------------------------------------------------------------
// t_shroud_transition_map class
// --------------------------------------------------------------------------

class t_shroud_transition_map : private t_uncopyable
{
public:
	// Types
	typedef t_shroud_transition			t_transition;
	typedef std::vector< t_transition >	t_transition_list;

	// Constructor
	t_shroud_transition_map( int size, int levels );

	// Member functions
	t_transition_list const &	get_transitions(
									t_level_map_point_2d const &	point ) const;
	void						take_transitions(
									t_level_map_point_2d const &	point,
									t_transition_list &				new_transitions );

private:
	// Types
	typedef t_copy_on_write_ptr< t_transition_list >	t_transition_list_ptr;
	typedef t_isometric_map< t_transition_list_ptr >	t_impl;

	// Data members
	t_impl	m_impl;
};

// --------------------------------------------------------------------------
// t_shroud_transition_map members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_shroud_transition_map::t_shroud_transition_map( int size, int levels )
	:	m_impl( size, levels, k_adventure_tile_height )
{
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_shroud_transition_map::t_transition_list const &
t_shroud_transition_map::get_transitions(
	t_level_map_point_2d const & point ) const
{
	assert( m_impl.is_valid( point ) );
	return *m_impl.get( point );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline void t_shroud_transition_map::take_transitions(
	t_level_map_point_2d const &	point,
	t_transition_list &				new_transitions )
{
	assert( m_impl.is_valid( point ) );
	t_transition_list_ptr new_transitions_ptr;
	if ( !new_transitions.empty() )
		new_transitions_ptr->swap( new_transitions );
	m_impl.get( point ) = new_transitions_ptr;
}

#endif // !defined( SHROUD_TRANSITION_MAP_H_INCLUDED )
